import 'dart:async';
import 'dart:math';

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:flutter_base/utils/shared/shared_export.dart';
import 'package:shared_preferences/shared_preferences.dart';

class SoftKeyboardManager with WidgetsBindingObserver {
  /// 单例模式
  static final SoftKeyboardManager _instance = SoftKeyboardManager._internal();
  static SharedPreferences? _prefs;
  factory SoftKeyboardManager() => _instance;

  SoftKeyboardManager._internal() {
    init();
  }

  /// 高度变化监听
  final _onHeightChangeListeners = <Function>[];

  void addHeightChangeListener(Function listener) {
    _onHeightChangeListeners.add(listener);
  }

  void removeHeightChangeListener(Function listener) {
    _onHeightChangeListeners.remove(listener);
  }

  void notifyHeightChangeListeners() {
    for (final listener in _onHeightChangeListeners) {
      listener();
    }
  }

  /// 状态变化监听
  final _onStateChangeListeners = <Function>[];

  void addStateChangeListener(Function listener) {
    _onStateChangeListeners.add(listener);
  }

  void removeStateChangeListener(Function listener) {
    _onStateChangeListeners.remove(listener);
  }

  void notifyStateChangeListeners() {
    for (final listener in _onStateChangeListeners) {
      listener();
    }
  }

  Timer? _debounce;

  init() async {
    /// 监听键盘弹出收起
    WidgetsBinding.instance.addObserver(this);
    _prefs = SharedStorage().prefs;
  }

  @override
  void didChangeMetrics() {
    super.didChangeMetrics();
    // clog("did change metrics");
    WidgetsBinding.instance.addPersistentFrameCallback((timeStamp) {
    if (Get.context == null) return;
      final inset = getSoftKeyboardHeight();
      if(inset == 0) {
        softKeyboardState = SoftKeyboardState.hide;
      }
    });

    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      if (Get.context == null) return;
      final inset = getSoftKeyboardHeight();
      currentSoftKeyboardHeight = inset;

      if (_debounce?.isActive ?? false) {
        _debounce?.cancel();
      }

      _debounce = Timer(const Duration(milliseconds: 500), (){
        if (Get.context == null) return;
        final inset = getSoftKeyboardHeight();

        if(softKeyboardState == SoftKeyboardState.showing) {
          softKeyboardState = SoftKeyboardState.show;
          /// 软键盘完全显示，更新软键盘高度
          softKeyboardHeight = inset;
        } else if(softKeyboardState == SoftKeyboardState.hiding) {
          softKeyboardState = SoftKeyboardState.hide;
        }
        _currentSoftKeyboardHeight = inset;
      });
    });


  }

  // void dispose() {
  //   WidgetsBinding.instance.removeObserver(this);
  //   _onHeightChangeListeners.clear();
  //   _onStateChangeListeners.clear();
  // }

  static double DEFAULT_KEYBOARD_HEIGHT = 300;

  double _softKeyboardHeight = _prefs?.getDouble(SharedKey.keyboardHeight) ??
      DEFAULT_KEYBOARD_HEIGHT;

  double get softKeyboardHeight => _softKeyboardHeight;

  set softKeyboardHeight(double value) {
    _softKeyboardHeight = value;

    notifyHeightChangeListeners();

    _prefs?.setDouble(SharedKey.keyboardHeight, value);
  }

  double _currentSoftKeyboardHeight = 0;
  double get currentSoftKeyboardHeight => _currentSoftKeyboardHeight;
  set currentSoftKeyboardHeight(double value) {
    final old = _currentSoftKeyboardHeight;
    _currentSoftKeyboardHeight = value;
    // clog("old :$old current :$value");
    /// 键盘高度增加，正在展开软键盘
    if(value > old) {
      softKeyboardState = SoftKeyboardState.showing;
    }
    ///键盘高度减少，正在收起软键盘
    if(value < old) {
      softKeyboardState = SoftKeyboardState.hiding;
    }
    ///键盘高度不变，无意义

    ///当前键盘高度大于默认/已保存键盘高度，即刻更新键盘高度（保存的键盘高度已小于实际键盘高度，同步更新）
    if (value > max(DEFAULT_KEYBOARD_HEIGHT, softKeyboardHeight)) {
      softKeyboardHeight = value;
    }
  }

  SoftKeyboardState _softKeyboardState = SoftKeyboardState.hide;

  SoftKeyboardState get softKeyboardState => _softKeyboardState;

  set softKeyboardState(value) {
    if(_softKeyboardState == value) return;
    _softKeyboardState = value;

    notifyStateChangeListeners();
  }

  getSoftKeyboardHeight() {
    return MediaQuery
        .of(Get.context!)
        .viewInsets
        .bottom;
  }

  updateSoftKeyboardState(){}

  /// 打开软键盘
  showSoftKeyboard(FocusNode focusNode) {
    if (softKeyboardState == SoftKeyboardState.show) return;
    focusNode.requestFocus();
  }

  /// 收起软键盘
  hideSoftKeyboard(FocusNode? focusNode) {
focusNode?.unfocus();
    if (softKeyboardState == SoftKeyboardState.hide) return;
    SystemChannels.textInput.invokeMethod('TextInput.hide');
  }
}

enum SoftKeyboardState { show, hide, showing, hiding }
